package com.syf.config.mybatisplus;

import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.incrementer.IKeyGenerator;
import com.baomidou.mybatisplus.extension.incrementer.H2KeyGenerator;
import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * MybatisPlus:
 *      分页插件
 *      乐观锁
 *      主键序列的生成(特殊情况用)
 *
 * @Mapper：
 *      作用：在接口类上添加了@Mapper，在编译之后会 生成相应的接口实现类
 *      添加位置：接口类上面
 *
 * @MapperScan:
 *      作用：指定要扫描的Mapper类的包的路径, 然后com.syf.mapper包下面的接口类，在编译之后都会生成相应的实现类
 *      添加位置：是在Springboot启动类上面添加
 *
 */
@Configuration
@MapperScan("com.syf.mapper")  //作用：指定要扫描的Mapper类的包的路径, 然后com.syf.mapper包下面的接口类，在编译之后都会生成相应的实现类
public class MybatisPlusConfig {

    /**
     * 分页插件
     */
    @Bean
    public PaginationInterceptor paginationInterceptor(){
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        paginationInterceptor.setDbType(DbType.MYSQL) ;
        return paginationInterceptor ;
    }


    /**
     * 5.乐观锁Version注解：
     *      乐观锁 : 故名思意十分乐观，它总是认为不会出现问题，无论干什么不去上锁！如果出现了问题，再次更新值测试
     *      悲观锁： 故名思意十分悲观，它总是认为总是出现问题，无论干什么都会上锁！再去操作！
     *
     *      乐观锁实现方式：
     *          取出记录时，获取当前 version
     *          更新时，带上这个version
     *          执行更新时， set version = newVersion where version = oldVersion
     *          如果version不对，就更新失败
     *
     *      乐观锁：
     *          1、先查询，获得版本号 version = 1
     *          2、-- B 线程抢先完成，这个时候 version = 2，会导致 A 修改失败！
     *
     *      乐观锁的作用：
     *          能自动检测多个事务对同一条数据进行的操作，并根据先胜原则，提交第一个事务，其他的事务提交时则抛出org.hibernate.StaleObjectStateException异常。
     *
     *      流程：
     *          1)给数据库表中增加version字段(默认值为1)
     *          2)我们实体类加对应的字段、注解(@Version)
     *          3)注册组件(乐观锁插件) --MyBatisPlusConfig.java
     *
     *      使用:
     *          在实体类属性上方添加注解： @Version
     */
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor(){
        OptimisticLockerInterceptor optimisticLockerInterceptor = new OptimisticLockerInterceptor();
        return optimisticLockerInterceptor ;
    }


    /**
     * 主键序列的生成(H2KeyGenerator)
     * 一般用这两种:
     *      ID_WORK 数字
     *      ID_WORK_STR 字符串
     */
   /* @Bean
    public IKeyGenerator iKeyGenerator(){
        H2KeyGenerator h2KeyGenerator = new H2KeyGenerator();
        return h2KeyGenerator ;
    }*/
}
